use bytes::BytesMut;
use std::fmt;

pub mod define;
pub mod errors;
pub mod packetizer;
pub mod unpacketizer;

// Chunk 基础头结构体
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ChunkBasicHeader {
    // Chunk 格式
    pub format: u8,
    // Chunk 流 ID
    pub chunk_stream_id: u32,
}

impl ChunkBasicHeader {
    pub fn new(format: u8, chunk_stream_id: u32) -> Self {
        Self {
            format,
            chunk_stream_id,
        }
    }
}

// 扩展时间戳类型
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum ExtendTimestampType {
    NONE,
    FORMAT0,
    FORMAT12,
}

// Chunk 消息头结构体
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct ChunkMessageHeader {
    // 时间戳
    pub timestamp: u32,
    // 消息长度
    pub msg_length: u32,
    // 消息类型 ID
    pub msg_type_id: u8,
    // 消息流 ID
    pub msg_streamd_id: u32,
    // 时间戳增量
    pub timestamp_delta: u32,
    // 扩展时间戳类型
    pub extended_timestamp_type: ExtendTimestampType,
}

impl ChunkMessageHeader {
    pub fn new(timestamp: u32, msg_length: u32, msg_type_id: u8, msg_stream_id: u32) -> Self {
        Self {
            timestamp,
            msg_length,
            msg_type_id,
            msg_streamd_id: msg_stream_id,
            timestamp_delta: 0,
            extended_timestamp_type: ExtendTimestampType::NONE,
        }
    }
}

// Chunk 头结构体，包含基本头和消息头
pub struct ChunkHeader {
    // 基本头
    pub basic_header: ChunkBasicHeader,
    // 消息头
    pub message_header: ChunkMessageHeader,
}

impl Default for ChunkHeader {
    fn default() -> Self {
        Self::new()
    }
}

impl ChunkHeader {
    pub fn new() -> ChunkHeader {
        ChunkHeader {
            basic_header: ChunkBasicHeader::new(0, 0),
            message_header: ChunkMessageHeader::new(0, 0, 0, 0),
        }
    }
}

// ChunkInfo结构体，包含基本头、消息头、有效载荷
#[derive(PartialEq, Eq, Clone)]
pub struct ChunkInfo {
    // 基本头
    pub basic_header: ChunkBasicHeader,
    // 消息头
    pub message_header: ChunkMessageHeader,
    // 有效载荷
    pub payload: BytesMut,
}

impl fmt::Debug for ChunkInfo {
    // 实现 Debug trait，格式化输出 ChunkInfo 结构体
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // 转化为十六进制
        let hex_payload = hex::encode(&self.payload);

        // 格式化为 0xXX的格式
        let formatted_payload = hex_payload
            .as_bytes()
            .chunks(2)
            .map(|chunk| format!("0x{}{}", chunk[0] as char, chunk[1] as char))
            .collect::<Vec<_>>()
            .join(", ");

        // 格式化输出 ChunkInfo
        write!(
            f,
            "ChunkInfo {{ basic_header: {:?}, message_header: {:?}, payload: {} }}",
            self.basic_header, self.message_header, formatted_payload
        )
    }
}

impl Default for ChunkInfo {
    fn default() -> Self {
        Self::new(0, 0, 0, 0, 0, 0, BytesMut::new())
    }
}

impl ChunkInfo {
    pub fn new(
        // 块流 ID
        csid: u32,
        // 块格式
        format: u8,
        // 时间戳
        timestamp: u32,
        // 消息长度
        msg_length: u32,
        // 消息类型ID
        msg_type_id: u8,
        // 消息流ID
        msg_stream_id: u32,
        // 有效载荷
        payload: BytesMut,
    ) -> Self {
        Self {
            basic_header: ChunkBasicHeader::new(format, csid),
            message_header: ChunkMessageHeader::new(
                timestamp,
                msg_length,
                msg_type_id,
                msg_stream_id,
            ),
            payload,
        }
    }
}
